//
//  SSEBDurationFormatter.m
//  Investigation Catalyst
//
//  Created by Tobias Haughton on 31/08/04.
//  Copyright 2004 Starline Software. All rights reserved.
//

// the SSEBDurationFormatter takes a string in the form of 0d 0h 0m 0s 0ms and converts that into a number of 
// seconds.

#import "SSEBDurationFormatter.h"


@implementation SSEBDurationFormatter

- (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString **)error
{
   if([string isEqualToString:[NSString string]]) {
      *anObject = [NSNumber numberWithDouble:0.0];
      return YES;
   }
   
   NSScanner *scanner = [NSScanner scannerWithString:string];
   BOOL retval = NO;
   NSRange daysPosition = [string rangeOfString:@"d" options:NSCaseInsensitiveSearch];
   NSRange hoursPosition = [string rangeOfString:@"h" options:NSCaseInsensitiveSearch];
   NSRange minutesPosition = [string rangeOfString:@"m" options:NSCaseInsensitiveSearch];
   NSRange secondsPosition = [string rangeOfString:@"s" options:NSCaseInsensitiveSearch];
   NSRange millisecondsPosition = [string rangeOfString:@"ms" options:NSCaseInsensitiveSearch];
   
   float days = 0;
   float hours = 0;
   float minutes = 0;
   float seconds = 0;
   float milliseconds = 0;
   
   NSArray *stringArray = [string componentsSeparatedByString:@" "];
   NSEnumerator *enumerator = [stringArray objectEnumerator];
   id enumObject;
   
   if(daysPosition.length == 0 && hoursPosition.length == 0 && minutesPosition.length == 0 && secondsPosition.length == 0 && millisecondsPosition.length == 0) { //we  dont have d, h, m, s or ms
      if([scanner scanFloat:&days]) {
         retval = YES;
      }
   } else { //we have 1 or more values
      while (enumObject = [enumerator nextObject]) {
         if([enumObject rangeOfString:@"d" options:NSCaseInsensitiveSearch].length) { //it's a day value
            scanner = [NSScanner scannerWithString:enumObject];
            if([scanner scanFloat:&days]) {
               retval = YES;
            }
         } else {
            if([enumObject rangeOfString:@"h" options:NSCaseInsensitiveSearch].length) {  //it's a hour value
               scanner = [NSScanner scannerWithString:enumObject];
               if([scanner scanFloat:&hours]) {
                  retval = YES;
               }
            } else {
               if([enumObject rangeOfString:@"ms" options:NSCaseInsensitiveSearch].length) {  //it's a ms value
                  scanner = [NSScanner scannerWithString:enumObject];
                  if([scanner scanFloat:&milliseconds]) {
                     retval = YES;
                  }
               }  else {
                  if([enumObject rangeOfString:@"s" options:NSCaseInsensitiveSearch].length) {  //it's a s value
                     scanner = [NSScanner scannerWithString:enumObject];
                     if([scanner scanFloat:&seconds]) {
                        retval = YES;
                     }
                  } else {
                     if([enumObject rangeOfString:@"m" options:NSCaseInsensitiveSearch].length) {  //it's a m value
                        scanner = [NSScanner scannerWithString:enumObject];
                        if([scanner scanFloat:&minutes]) {
                           retval = YES;
                        }
                     }
                  }
               }
            }
         }
      }      
   }
   
   if(retval) { //we got some values put them into a nsnumber
      double total = 0;
      total = (days * 86400); //num seconds in a day
      total += (hours * 3600);
      total += (minutes * 60);
      total += seconds;
      total += (milliseconds / 1000.0);
      
      *anObject = [NSNumber numberWithDouble:total];
   }
   
   return retval;
}

- (NSString *)stringForObjectValue:(id)anObject
{
   if (![anObject isKindOfClass:[NSNumber class]]) {
      return nil;
   }

   if([anObject doubleValue] > 0) {
      double days = 0.0;
      double hours = 0.0;
      double minutes = 0.0;
      double seconds = floor([anObject doubleValue]);
      double baseMilli = ([anObject doubleValue] - seconds);
      int milliseconds = nearbyint(baseMilli * 1000.0);
      
      if(seconds / 86400.0 >= 1) {
         //there is at least 1 whole day here
         days = floor(seconds / 86400.0);
         //remove the seconds that we used for the day value
         seconds -= (days * 86400);
      }
      
      if(seconds / 3600.0 >= 1) {
         //there is at least 1 whole hour here
         hours = floor(seconds / 3600.0);
         //remove the seconds that we used for the day value
         seconds -= (hours * 3600);
      }
         
      if(seconds / 60.0 >= 1) {
         //there is at least 1 whole minute here
         minutes = floor(seconds / 60.0);
         //remove the seconds that we used for the day value
         seconds -= (minutes * 60);
      }
      
      //got all the info we need build the string
      NSString *durationString = [NSString string];
      
      if(days != 0) {
         //add the day variable
         int d = (int)days;
         durationString = [durationString stringByAppendingString:[NSString stringWithFormat:@"%dd ", d]];
      }
      
      if(hours != 0) {
         //add the hours variable
         int h = (int)hours;
         durationString = [durationString stringByAppendingString:[NSString stringWithFormat:@"%dh ", h]];
      }
      
      if(minutes != 0) {
         //add the minutes variable
         int m = (int)minutes;
         durationString = [durationString stringByAppendingString:[NSString stringWithFormat:@"%dm ", m]];
      }
      
      if(seconds != 0) {
         //add the seconds variable
         int s = (int)seconds;
         durationString = [durationString stringByAppendingString:[NSString stringWithFormat:@"%ds ", s]];
      }
      
      if(milliseconds != 0) {
         //add the milliseconds variable
         durationString = [durationString stringByAppendingString:[NSString stringWithFormat:@"%dms", milliseconds]];
      }
      
      return durationString;
   } else {
      return @"0d 0h 0m 0s 0ms";
   }
}

@end
